package com.admin.common.exception;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import com.alibaba.fastjson.JSONObject;
import com.admin.common.enums.EnumResult;
import com.admin.vo.SimpleResultVO;
import org.springframework.web.servlet.NoHandlerFoundException;

/**
 * 默认全局异常处理类
 * 
 * @author ZY
 * @date 2018/10/18
 */
@ControllerAdvice
@ResponseBody
public class GlobalDefaultExceptionHandler {

    private Logger logger = LoggerFactory.getLogger(GlobalDefaultExceptionHandler.class);

    /**
     * 处理 HTTP 404 错误
     */
    @ExceptionHandler({NoHandlerFoundException.class})
    @ResponseStatus(HttpStatus.NOT_FOUND)
    @ResponseBody
    public void handleNotFound(HttpServletRequest req, Exception ex, HttpServletResponse response) {
        SimpleResultVO result = new SimpleResultVO();
        result.setCode(HttpStatus.NOT_FOUND.value());
        result.setMsg("无该资源: "+ req.getRequestURI());
        writeJson(result, response);
    }

    @ExceptionHandler({IllegalArgumentException.class})
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    @ResponseBody
    public void handleNotFoundBAD_REQUEST(HttpServletRequest req, Exception ex, HttpServletResponse response) {
        SimpleResultVO result = new SimpleResultVO();
        result.setCode(HttpStatus.BAD_REQUEST.value());
        result.setMsg("无该资源: "+ req.getRequestURI());
        writeJson(result, response);
    }

    /**
     * 处理 HTTP 500 错误
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public void handleInternalServerError(HttpServletRequest req, Exception ex,HttpServletResponse response) {
        SimpleResultVO result = new SimpleResultVO();
        result.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
        result.setMsg("服务器内部错误: " + ex.getMessage());
        writeJson(result, response);
    }

    @ExceptionHandler(Throwable.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    @ResponseBody
    public void handleOtherExceptions(HttpServletRequest req, Throwable ex, HttpServletResponse response) {
        SimpleResultVO result = new SimpleResultVO();
        result.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
        result.setMsg("系统内部错误: " + ex.getMessage());
        writeJson(result, response);
    }

    /**
     * 校验访问权限异常
     * 
     * @param e
     * @return
     */
    @ExceptionHandler(value = AuthorizationException.class)
    public void handAuthorizationException(AuthorizationException e, HttpServletResponse response) {
        logger.error("校验访问权限异常：", e);
        SimpleResultVO result = new SimpleResultVO();
        result.setCode(EnumResult.USER_CHECK_ACCES_PERMISSION_ERROR.getCode());
        result.setMsg(EnumResult.USER_CHECK_ACCES_PERMISSION_ERROR.getMsg());
        writeJson(result, response);
    }

    /**
     * 无访问权限
     * 
     * @param e
     * @return
     */
    @ExceptionHandler(value = UnauthorizedException.class)
    public void handUnauthorizedException(UnauthorizedException e, HttpServletResponse response) {
        SimpleResultVO result = new SimpleResultVO();
        result.setCode(EnumResult.USER_NO_ACCESS_PERMISSION.getCode());
        result.setMsg(EnumResult.USER_NO_ACCESS_PERMISSION.getMsg());
        writeJson(result, response);
    }

    /**
     * session未找到(sessionId错误或session从redis等清除失效，已经不存在了)
     * 
     * @param e
     * @param response
     */
    // @ExceptionHandler(value = UnknownSessionException.class)
    // public void handUnknownSessionException(UnknownSessionException e, HttpServletResponse response) {
    // SimpleResultVO result = new SimpleResultVO();
    // result.setCode(EnumResult.USER_NOT_LOGIN.getCode());
    // result.setMsg(EnumResult.USER_NOT_LOGIN.getMsg());
    // writeJson(result, response);
    // }

    /**
     * 业务异常
     * 
     * @param e
     * @return
     */
    @ExceptionHandler(value = BizException.class)
    public void handBizException(BizException e, HttpServletResponse response) {
        SimpleResultVO result = new SimpleResultVO();
        result.setCode(e.getCode());
        result.setMsg(e.getMsg());
        writeJson(result, response);
    }

    /**
     * 其它异常
     * 
     * @param e
     * @return
     */
    /*@ExceptionHandler(value = Exception.class)
    public void handException(Exception e, HttpServletResponse response) {
        logger.error("系统异常：", e);
        SimpleResultVO result = new SimpleResultVO();
        result.setCode(EnumResult.OPERATION_ERROR.getCode());
        result.setMsg(EnumResult.OPERATION_ERROR.getMsg());
        writeJson(result, response);
    }*/

    /**
     * 以json形式输出异常信息
     * 
     * @param result
     * @param response
     */
    private void writeJson(SimpleResultVO result, HttpServletResponse response) {
        PrintWriter out = null;
        try {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/json; charset=utf-8");
            out = response.getWriter();
            out.write(JSONObject.toJSONString(result));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }



}
